#include <stdio.h>
#include <string.h>
#include "relic.h"
#include "sqft_conf.h"
#include <math.h>
#include <sys/time.h>


long long unsigned getTimeDifff(struct timeval start, struct timeval stop);

int MAX=100, i;
struct timeval start, stop;
bn_t a, b, c, d, e, p;
bn_t f[2], g[2], h[2], k[2];


/**--------------------------------------------------------------------*/
/**
 * Funcao para calculo de intervalo de tempo de execuao
 * Precisao: microsegundos (us)
 */
 
long long unsigned getTimeDifff(struct timeval start, struct timeval stop) {
	long long unsigned time;
	time = (float) (stop.tv_sec - start.tv_sec)*1000000;
	time += ((float)(stop.tv_usec - start.tv_usec));
	return time;
}




/**--------------------------------------------------------------------*/

void swt() {
	bn_set_dig(c, 39);
	bn_gen_prime(p, BN_BITS);
	bn_rand(a, BN_POS, bn_bits(p)-1);
	
	gettimeofday(&start, NULL);
	for (i=0; i<MAX; i++) {
		bn_pol_mul_swt(b, a, c, p);
	}
	gettimeofday(&stop, NULL);
	printf("\nswt time:\t\t%llu", getTimeDiff(start, stop));
	
	gettimeofday(&start, NULL);
	for (i=0; i<MAX; i++) {
		bn_mul_dig(d, a, c->dp[0]);
		bn_mod(d, d, p);
	}
	gettimeofday(&stop, NULL);
	printf("\nmuldig_mod time:\t%llu", getTimeDiff(start, stop));
	
	if (bn_cmp(b, d) != CMP_EQ) printf("\nFódeuu");
	
}


/**--------------------------------------------------------------------*/


void muldig_mod() {
	bn_set_dig(c, 39);
	bn_gen_prime(p, BN_BITS);
	bn_rand(a, BN_POS, bn_bits(p)-1);
	gettimeofday(&start, NULL);
	for (i=0; i<MAX; i++) {
		bn_mul_dig(b, a, c->dp[0]);
		bn_mod(b, b, p);
	}
	gettimeofday(&stop, NULL);
	printf("\nmuldig_mod time:\t%llu", getTimeDiff(start, stop));
	
}



/**--------------------------------------------------------------------*/




/**--------------------------------------------------------------------*/


int main() {
	
	if (core_init() != STS_OK) {
		core_clean();
		return 1;
	}
	
	bn_null(a);
	bn_null(b);
	bn_null(c);
	bn_null(d);
	bn_null(e);
	bn_null(p);
	bn_pol_null(f);
	bn_pol_null(g);
	bn_pol_null(h);
	bn_pol_null(k);
	
	swt();
	//muldig_mod();
	
	
	bn_free(a);
	bn_free(b);
	bn_free(c);
	bn_free(d);
	bn_free(e);
	bn_free(p);
	bn_pol_free(f);
	bn_pol_free(g);
	bn_pol_free(h);
	bn_pol_free(k);
	core_clean();
	
	return 0;
}
